package com.zzg.search.service.impl;

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;

import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zzg.search.constant.SearchConstants;
import com.zzg.search.exception.update.ClientUpdateException;
import com.zzg.search.service.CommonService;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class CommonServiceImpl implements CommonService {
	@Autowired
	private TransportClient client;

	@Override
	public GetResponse select(String index, String type, String id) {
		// TODO Auto-generated method stub
		return client.prepareGet(index, type, id).get();
	}

	@Override
	public IndexResponse insert(String index, String type, XContentBuilder builder) {
		// TODO Auto-generated method stub
		return client.prepareIndex(index, type).setSource(builder).get();
	}

	@Override
	public DeleteResponse delete(String index, String type, String id) {
		// TODO Auto-generated method stub
		return client.prepareDelete(index, type, id).get();
	}

	@Override
	public UpdateResponse update(String index, String type, String id, XContentBuilder builder,
			Map<String, Object> parames) {
		// TODO Auto-generated method stub
		UpdateResponse response = null;
		UpdateRequest update = new UpdateRequest(index, type, id);
		try {
			builder.startObject();
			Iterator entries = parames.entrySet().iterator();
			while (entries.hasNext()) {
				Map.Entry entry = (Map.Entry) entries.next();
				String key = (String) entry.getKey();
				Object value = entry.getValue();
				builder.field(key, value);
			}
			builder.endObject();

			update.doc(builder);
			response = client.update(update).get();
		} catch (Exception e) {
			log.error(e.getMessage());
			throw new ClientUpdateException(null, e.getMessage());
		} 
		return response;
	}

	@Override
	public SearchResponse multiQuery(String keyword, String type, BoolQueryBuilder builder, Map<String, Object> must, Map<String,Object[]> rang) {
		// 组装查询条件
	    BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
	    // 必须条件
	    Iterator mustEntry = must.entrySet().iterator();
	    while (mustEntry.hasNext()) {
			Map.Entry entry = (Map.Entry) mustEntry.next();
			String key = (String) entry.getKey();
			Object value = entry.getValue();
			boolQuery.must(QueryBuilders.matchQuery(key, value));
		}
	    // 范围条件
	    Iterator rangEntry = rang.entrySet().iterator();
	    while(rangEntry.hasNext()){
	    	Map.Entry entry = (Map.Entry) rangEntry.next();
			String key = (String) entry.getKey();
			Object[] value = (Object[]) entry.getValue();
			RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(key).from(value[0]).to(value[1]);
			boolQuery.filter(rangeQuery);
	    }
	    
	    SearchRequestBuilder requestBuilder = client.prepareSearch(keyword).setTypes(type).setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setQuery(boolQuery).setFrom(SearchConstants.PAGE_NO).setSize(SearchConstants.PAGE_SIZE);
		return requestBuilder.get();
	}

}
